<?php
/*
 +-------------------------------------------------------------------+
 |                   database.php                                 |
 |                                                                   |
 | Copyright ?                          www.gde.sclab.clarkson.edu   |
 | Author: Demetrios Dimatos            www.dimatos.net              |
 | Created: August 2006                 Last modified: Oct 15, 2006  |
 +-------------------------------------------------------------------+
 | These functions are used throught the project for connecting,     |
 | querying and displaying the results (limited displaying, see      |
 | html.php for display functions)                                   |
 +-------------------------------------------------------------------+
*/

//Start the SESSION vars
if(session_id() == "")
{
	session_start();
}
/* Include the configuation file*/
include_once('/var/www/gde-1.0/htdocs/config.php');
/* Include adodb */
include_once(Config::base_path.Config::adodb_path."adodb.inc.php");
// Include exceptions for adodb
include_once(Config::base_path.Config::adodb_path."adodb-exceptions.inc.php");
// Include the html paging functions
include_once(Config::base_path.Config::adodb_path.'adodb-pager.inc.php');

/**
 * Defined variables to indicate where to connect to find the database
 * BACKEND - sends the query to the database constants defined in the config.php
 *@author Demetrios Dimatos
 */
define("BACKEND",0);

/**
 * Defined variables to indicate where to connect to find the database
 * DOMAIN_SPECIFIC - sends the query to the database defined by the users login information.
 *@author Demetrios Dimatos
 */
define("DOMAIN_SPECIFIC",1);

/**
 * Makes a Non-persistent connect to data source or server with exceptions
 *
 * @param string $dbtype - type of database, mysql,db2,oracle etc
 * @param string $dbhost - host location, localhost, myserver:3062, 127.0.0.1, etc
 * @param string $dbusername - username for the database connection
 * @param string $dbpassword - password for the username database connection
 * @param string $dbdatabase - name of the database to connect to
 * @param integer $error_s - 0 for no exceptions, 1 for exceptions to stdout
 * @return adodb object - adodb Non-persistent connect to data source
 * @author Demetrios Dimatos
 */
function db_connect($dbtype, $dbhost, $dbusername, $dbpassword, $dbdatabase, $error_s)
{
	global $dbconn;

	try
	{
		
		$dbconn = NewADOConnection($dbtype);
		$dbconn->Connect($dbhost, $dbusername, $dbpassword, $dbdatabase);
		if($error_s == 1)
		{
			$dbconn->debug=1;
		}
	}
	catch (ADODB_Exception $e)
	{
		echo "Database Connection Error:".$e->getMessage();
	}
	catch (Exception $e)
	{
		var_dump($e);
		adodb_backtrace($e->getTrace());
	}
	return $dbconn;
}

/**
 * Makes a Persistent connect to data source or server with exceptions
 *
 * @param string $dbtype - type of database, mysql,db2,oracle etc
 * @param string $dbhost - host location, localhost, myserver:3062, 127.0.0.1, etc
 * @param string $dbusername - username for the database connection
 * @param string $dbpassword - password for the username database connection
 * @param string $dbdatabase - name of the database to connect to
 * @param integer $error_s - 0 for no exceptions, 1 for exceptions to stdout
 * @return adodb object - adodb Non-persistent connect to data source
 * @author Demetrios Dimatos
 */
function db_pconnect($dbtype, $dbhost, $dbusername, $dbpassword, $dbdatabase, $error_s)
{
	global $dbconn;

	try
	{
		
		$dbconn = NewADOConnection($dbtype);
		$dbconn->PConnect($dbhost, $dbusername, $dbpassword, $dbdatabase);
		if($error_s == 1)
		{
			$dbconn->debug=1;
		}
	}
	catch (ADODB_Exception $e)
	{
		echo "Database Connection Error:".$e->getMessage();
	}
	catch (Exception $e)
	{
		var_dump($e);
		adodb_backtrace($e->getTrace());
	}
	return $dbconn;
}

// Set the database search option, if domain_specific then use the $SESSION Login
// still need to set up SESSION Var's for db_type,db_host,db_database in forum users	
/**
 * Peforms a query without having to make a seperate database connection decoupling the backend
 * from the domain specific queries
 *
 * @param string $sql - Valid SQL statement
 * @param integer $connection_type - sets the connection either to backend or not as well as persistent
 * or non persistent connection based on DOMAIN_SPECIFIC or BACKEND
 * @param string $FETCH_MODE - sets the type of resultset returned, ADODB_FETCH_NUM, ADODB_FETCH_ASSOC 
 * @return adodb resultset object containg the result
 * @author Demetrios Dimatos
 */
function doQuery($sql,$connection_type,$FETCH_MODE = "ADODB_FETCH_DEFUALT")
{
	global $dbconn;
	global $result;
	
	if($connection_type == BACKEND) 	//Backend, use the pre-defined user to obtain db info for guest users
	{
		$dbconn = db_connect(Config::db_type,Config::db_host, Config::db_username,Config::db_password,Config::db_database,Config::errors);
		$dbconn->SetFetchMode($FETCH_MODE);
		$result = $dbconn->Execute($sql); 
	}
	elseif ($connection_type == DOMAIN_SPECIFIC) // Domain-specific, so user user logged-in info
	{
		$dbconn = db_pconnect(Config::db_type,Config::db_host,$_SESSION['username'],$_SESSION['password'],$_SESSION['databaseName'],Config::errors);
		$dbconn->SetFetchMode($FETCH_MODE);
		$result = $dbconn->Execute($sql);
	}
	
	return $result;
}

/**
 * describeDatabase - obtains desciption of a datbase
 *
 * @param string $databaseName - name of databse
 * @param string $table - name of table
 * @return adodb resultset object containg the result
 * @author Demetrios Dimatos
 */
function describeDatabase($databaseName,$table)
{
	global $result;
 	try
 	{
 		$sql = 'describe '.$databaseName.'.'.$table;
		$result = doQuery($sql,BACKEND);
 	}
	catch(Exception $e)
	{
		die( "ERROR executing query ".$e->getMessage());
	}
		
	if($result->RecordCount() == 0)
	{
		return $result = 0;
	}
	return $result;
}

/**
 * Peforms a qeury limiting the number of results, this is acts the same as using LIMIT in SQL but this
 * function will will work across all database platforms.
 *
 * @param string $sql - SQL Query
 * @param integer $limit - maximum number of records to be returned
 * @param integer $connection_type - sets the connection either to backend or not as well as persistent
 * or non persistent connection based on DOMAIN_SPECIFIC or BACKEND
 * @return adodb resultset object containg the result
 */
function selectLimit($sql,$limit,$connection_type)
{
	global $result;
	$result=0;
	
	if($connection_type == BACKEND) 	//Backend, use the pre-defined user to obtain db info for guest users
	{
		$dbconn = db_connect(Config::db_type,Config::db_host, Config::db_username,Config::db_password,Config::db_database,Config::errors);
		try 
		{
			$result = $dbconn->SelectLimit($sql,$limit); 
		}
		catch (Exception $e)
		{
			die( "ERROR executing query ".$e->getMessage());
		}
	}
	elseif ($connection_type == DOMAIN_SPECIFIC) // Domain-specific, so user user logged-in info
	{
		$dbconn = db_pconnect(Config::db_type,Config::db_host,$_SESSION['username'],$_SESSION['password'],$_SESSION['databaseName'],Config::errors);
		try 
		{
			$result = $dbconn->SelectLimit($sql,$limit);
		}
		catch (Exception $e)
		{
			die( "ERROR executing query ".$e->getMessage());
		}
	}
	
	return $result;
}

/**
 * Converts a adodb resultset object containg the result to an array
 *
 * @param adodb result object  $result - query returned from valid SQL
 * @return array with all the query results
 */
function result2array($result)
{
	$array_return = array();
	$index=0;
	while(!$result->EOF)
 	{
 		// For histograms we don't want empty values else func array_count_values fails so place null.
 		for($num = 0; $num < $result->FieldCount(); $num++)
 		{
 			if($result->fields[$num] == "")
 			{
 				$array_return[$index++]="NULL";
 			}
 			else
 			{
 				$array_return[$index++]=$result->fields[$num];
 			}
 		}
 		$result->MoveNext();
 	}
 	
 	return $array_return;
}

// Print record sets with paginating
/**
 * Prints the record set with paginating, similar to record2PagingHtml() only that a database connection
 * is made in this function making it more versitile.
 *
 * @param string $sql - SQL query
 * @param integer $rows_per_page - number of rows to pagenate on
 * @param string $id -  pager object needs a unique ID, If you put more than one pager object in 
 * a page, ADODB_Pager needs to tell them apart so the next and previous links advance the correct pager
 * @author Demetrios Dimatos
 */
function record2PagingHtml_2($sql,$rows_per_page,$id="self")
{
	//$sql = 'select * from forum_users where username="'.Config::db_username.'"';
	$database_connection = db_pconnect(Config::db_type,Config::db_host,$_SESSION['username'],$_SESSION['password'],$_SESSION['selected_database'],Config::errors);
	$pager = new ADODB_Pager($database_connection,$sql,$id,true);
	$pager->Render($rows_per_page);
}
?>